"""功能分析：
        购物车中的商品信息和商品勾选状态是分开存储的，但是我们现在需要一个接口提供所有数据，所以我们需要整合/重构数据的结构
        cart_<user_id>:{
            <course_id>:<expire>,
            <course_id>:<expire>,
            ...
        }

        selected_<user_id>:{<course_id>,<course_id>,....}

        目标：把数据整合成一个列表，列表中每一个成员就是商品字典：
        data = [
            {
                course_id:<course_id>,
                expire:<expire>,
                selected:<selected>,
            },
            {
                course_id:<course_id>,
                expire:<expire>,
                selected:<selected>,
            },
            {
                course_id:<course_id>,
                expire:<expire>,
                selected:<selected>,
            },
        ]
"""
from django.shortcuts import render

# Create your views here.
from rest_framework.viewsets import ViewSet
from rest_framework.permissions import IsAuthenticated
from courses.models import Course,CourseExpire
from rest_framework.response import Response
from rest_framework import status
from django_redis import get_redis_connection
'''
drf中,接受put,patch和post,接收请求体都使用request.data
      接受get,delete,接收参数，只能使用request.query_params,
原因是: http请求中.get,delete是没有请求体的.而post,put和patch有请求体
'''
class CartAPIView(ViewSet):
    permission_classes = [IsAuthenticated]
    def add_cart(self,request):
        '''
        添加商品到购物车
        :param request:
        :return:
        '''
        #接收客户端提交的数据[用户id，课程id，有效期和勾选状态]
        user_id = request.user.id
        course_id = request.data.get('course_id')
        expire = 0 # 默认有效期，0表示没有勾选
        #效验数据
        try:
            Course.objects.get(is_show=True,is_delete=False,pk=course_id)
        except Course.DoesNotExist:
            return Response({'message':"当前商品不存在"})
        # todo 判断用户是否已经购买了本商品，如果已经购买并在有效期使用范围内，则不能继续加入购物车
        #连接redis
        redis_conn = get_redis_connection("cart")
        #保存数据
        pipe = redis_conn.pipeline()
        pipe.multi()
        pipe.hset("cart_%s"%user_id,course_id,expire)
        pipe.sadd("selected_%s"%user_id,course_id)#刚加入购物车的商品默认是勾选状态
        pipe.execute()
        cart_length = redis_conn.hlen("cart_%s"%user_id)
        #响应结果
        return Response({"message":"成功添加商品到购物车", "cart_length":cart_length})
    def get_cart(self,request):
        '''
        获取购物车中的商品信息
        :param request:
        :return:
        '''
        # 获取用户id
        user_id = request.user.id

        # 根据用户id到购物车中查询商品信息
        redis_conn = get_redis_connection("cart")
        cart_hash = redis_conn.hgetall("cart_%s"%user_id)
        selected_set = redis_conn.smembers("selected_%s"%user_id)
        # 根据购物车中的商品id到mysql中提取商品具体信息
        data=[]
        for course_id_bytes,expire_bytes in cart_hash.items():
            course_id = course_id_bytes.decode()
            expire =  int( expire_bytes.decode() )
            try:
                course = Course.objects.get(pk=course_id,is_show=True,is_delete=False)
            except Course.DoesNotExist:
                #如果当前商品被下架或者被逻辑删除了则不显示到购物车商品列表中
                continue
            data.append({
                "course_id":course_id,
                "course_img":course.course_img.url,
                "course_name":course.name,
                "expire_list":course.expire_list,
                "expire_time":expire,
                "price": course.get_discount_price_by_expire(expire),
                "selected":course_id_bytes in selected_set,

            })
            #返回结果
        return Response(data)
    """http请求中，get/delete没有请求体, post/put/patch有请求体"""
    def change_selected_status(self,request):
        '''
        修改商品勾选状态
        :param request:
        :return:
        '''
        # 获取客户端提交的数据[user_id, course_id, selected]
        user_id = request.user.id
        course_id = request.data.get("course_id")
        selected = request.data.get("selected")
        # if type(course_id)==list:
        #     # 连接redis
        #     redis_conn = get_redis_connection("cart")
        #
        #     # 切换勾选状态
        #     if selected:
        #         """全部勾选"""
        #         for course in course_id:
        #             if course.get('selected')==True:
        #                 continue
        #             redis_conn.sadd("selected_%s" % user_id, course.get('course_id'))
        #     else:
        #         """全部不勾选"""
        #         for course in course_id:
        #             print(course,type(course))
        #             if course.get('selected')==False:
        #                 continue
        #             redis_conn.srem("selected_%s" % user_id, course.get('course_id'))
        #     return Response({"message": "切换全部勾选状态成功！"})

        # 连接redis
        redis_conn = get_redis_connection("cart")

        # 切换勾选状态
        if selected:
            """勾选"""
            redis_conn.sadd("selected_%s" % user_id, course_id)
        else:
            """去除勾选"""
            redis_conn.srem("selected_%s" % user_id, course_id)

        # 返回结果
        return Response({"message": "切换勾选状态成功！"})
    def delete_cart(self,request):
        """删除购物车中的商品"""
        # 接受客户端提交的数据[user_id, course_id]
        user_id = request.user.id
        course_id = request.query_params.get("course_id")

        try:
            Course.objects.get(id=course_id)
        except Course.DoesNotExist:
            return Response({"message":"删除商品数据成功"})

        # 连接redis
        redis_conn = get_redis_connection("cart")

        # 根据用户id删除指定商品id的数据[从hash和set中删除]
        pipe = redis_conn.pipeline()
        pipe.multi()
        pipe.hdel("cart_%s" % user_id, course_id)
        pipe.srem("selected_%s" % user_id, course_id)
        pipe.execute()

        # 返回结果
        return Response({"message":"删除商品数据成功"})
    def change_expire(self,request):
        """切换课程的有效期选项"""
        # 获取用户提交过来的数据[用户ID,课程ID, 选项]
        user_id = request.user.id
        course_id = request.data.get("course_id")
        expire_time = request.data.get("expire")

        # 验证数据
        try:
            Course.objects.get(pk=course_id,is_show=True,is_delete=False)
        except Course.DoesNotExist:
            return Response({"message":"切换有效期的课程不存在！"}, status=status.HTTP_400_BAD_REQUEST)

        if expire_time > 0:
            try:
                CourseExpire.objects.get(course_id=course_id, expire=expire_time)
            except CourseExpire.DoesNotExist:
                return Response({"message":"当前课程的有效期选项不存在！"}, status=status.HTTP_400_BAD_REQUEST)

        # 连接redis
        redis_conn = get_redis_connection("cart")

        # 修改有效期选项
        redis_conn.hset("cart_%s" % user_id, course_id, expire_time)

        # 返回结果
        return Response({"message":"修改有效期选项成功！"})

    def get_select_course(self, request):
        """获取购物车中被勾选的商品信息"""
        # 获取用户id
        user_id = request.user.id
        # 根据用户id到购物车中查询商品信息
        redis_conn = get_redis_connection("cart")
        cart_hash = redis_conn.hgetall("cart_%s" % user_id)
        selected_set = redis_conn.smembers("selected_%s" % user_id)

        # 根据购物车中的商品id到mysql中提取商品具体信息
        data = []
        for course_id_bytes in selected_set:
            course_id = course_id_bytes.decode()
            expire = int(cart_hash[course_id_bytes].decode())

            try:
                course = Course.objects.get(pk=course_id, is_show=True, is_delete=False)
            except Course.DoesNotExist:
                # 如果当前商品被下架或者被逻辑删除了则不显示到购物车商品列表中
                continue

            try:
                ret = CourseExpire.objects.get(course_id=course_id, expire=expire)
                expire_text = ret.text
            except:
                expire_text = "永久有效"

            data.append({
                "course_id": course.id,
                "course_img": course.course_img.url,
                "course_name": course.name,
                "discount_name": course.discount_name,
                "expire_text": expire_text,
                "original_price": course.get_price_by_expire(expire),
                "discount_price": course.get_discount_price_by_expire(expire),
            })

        # 返回结果
        return Response(data)